home *** CD-ROM | disk | FTP | other *** search
/ El Mac 9 / El Mac 9.iso / Shareware / Demos / Igor Demo Pro / 1 PutContentsIn Igor Pro Folder / WaveMetrics Procedures / Image and Contour Plots / Image Processing Panel < prev    next >
Encoding:
Text File  |  1996-01-29  |  9.3 KB  |  387 lines  |  [TEXT/IGR0]

  1. // This package creates a control panel that makes it easy to perform common
  2. // image processing techniques such as gaussian blur and edge finding.
  3.  
  4.  
  5. #pragma rtGlobals=1
  6.  
  7.  
  8. Macro CreateImageProcessingPanel()
  9.     String dfSav= GetDataFolder(1)
  10.     NewDataFolder/O/S root:Packages
  11.     NewDataFolder/O/S WMImProcess
  12.     Variable/G size=3,passesNxN=1,passes3x3=1
  13.     SetDataFolder dfSav
  14.     
  15.     WMImageProcessingPanel()
  16. end
  17.  
  18.  
  19. // This routine is used to fetch a full path to the image wave in the top
  20. // graph. A zero length string is returned if failure.
  21. //
  22. Function/S WMGetImageWave()
  23.     String s= ImageNameList("", ";")
  24.     Variable p1= StrSearch(s,";",0)
  25.     if( p1<0 )
  26.         return ""            // no image in top graph
  27.     endif
  28.     s= s[0,p1-1]
  29.     Wave w= ImageNameToWaveRef("", s)
  30.     return GetWavesDataFolder(w,2)        // full path to wave including name
  31. end
  32.  
  33. // This routine makes backups of the data in the same data folder as
  34. // the source wave. If a wave of the same name but with the suffex _Back
  35. // does NOT exist then the source is duplicated as such a name. This wave
  36. // is used for the restore button.
  37. // The source wave is always duplicated as a wave with the suffex _UnDo
  38. // which is used by the Undo button.
  39. //
  40. Function WMSaveWaveBackups(w)
  41.     Wave w
  42.  
  43.     String s= GetWavesDataFolder(w,1)
  44.     String dfSav= GetDataFolder(1)
  45.     SetDataFolder s
  46.     String bakName= NameOfWave(w)+"_Back"
  47.     if( exists(bakName) != 1 )
  48.         Duplicate/O w,$bakName
  49.     endif
  50.     Duplicate/O w,$(NameOfWave(w)+"_UnDo")
  51.     SetDataFolder dfSav
  52. end
  53.  
  54. // This routine restores wave w from backups that have been saved using WMSaveWaveBackups
  55. // It can also delete the backups depending on kind:
  56. // use -1 to kill backups, use 0 to restore from _UnDo, 1 to restore from _Back
  57. // Returns 0 if success, 1 if backups did not exist and tried restore or undo
  58. // When doing a restore the current data is stored in _UnDo so you can undo a restore
  59. //
  60. Function WMRestoreWaveBackups(w,kind)
  61.     Wave w
  62.     Variable kind
  63.  
  64.     variable fail= 1
  65.  
  66.     String s= GetWavesDataFolder(w,1)
  67.     String dfSav= GetDataFolder(1)
  68.     SetDataFolder s
  69.  
  70.     String bakName= NameOfWave(w)+"_Back"
  71.     String undoName= NameOfWave(w)+"_UnDo"
  72.  
  73.     do
  74.         if( kind == -1 )
  75.             KillWaves/Z $bakName,$undoName        // don't care if they existed or not
  76.             fail= 0
  77.             break
  78.         endif
  79.         if( kind == 0 )
  80.             if( exists(undoName) == 1 )
  81.                 NewDataFolder rwtmp    // tmp wave may or may not be created here
  82.                 Duplicate/O $undoName,:rwtmp:tmpw
  83.                 Duplicate/O w,$undoName
  84.                 Duplicate/O :rwtmp:tmpw,w
  85.                 KillDataFolder rwtmp
  86.                 fail= 0
  87.             endif
  88.         else // must be 1
  89.             if( exists(bakName) == 1 )
  90.                 Duplicate/O w,$undoName
  91.                 Duplicate/O $bakName,w
  92.                 fail= 0
  93.             endif
  94.         endif
  95.     while(0)
  96.     SetDataFolder dfSav
  97.     return fail
  98. end
  99.  
  100.  
  101. Function WMBPNxNDoIt(ctrlName) : ButtonControl
  102.     String ctrlName
  103.  
  104.     String pw= WMGetImageWave()
  105.     Wave w= $pw
  106.     if( !WaveExists(w) )
  107.         beep
  108.         return 0
  109.     endif
  110.  
  111.     if( CmpStr("NxNDoIt",ctrlName) == 0 )
  112.         ControlInfo popNxN
  113.         NVAR passesNxN= root:Packages:WMImProcess:passesNxN
  114.     else
  115.         ControlInfo pop3x3
  116.         NVAR passesNxN= root:Packages:WMImProcess:passes3x3
  117.     endif
  118.  
  119.     String keyword= S_value
  120.     if( CmpStr(keyword,"NaNZapMedian") == 0 )
  121.         if( (WaveType(w) %& (2+4) ) == 0 )
  122.             Abort "Integer image has no NANs to zap!"
  123.             return 0
  124.         endif
  125.     endif
  126.     WMSaveWaveBackups(w)
  127.     NVAR size= root:Packages:WMImProcess:size
  128.     MatrixFilter/N=(size)/P=(passesNxN) $keyword, w
  129. End
  130.  
  131.  
  132. Function/S WMLoadKernel()
  133.     String rval= ""
  134.     
  135.     String dfSav=GetDataFolder(1)
  136.     SetDataFolder WMGetSetKernelDFVariable("")
  137.     NewDataFolder/S lktmp
  138.     LoadWave/G/M/A=kernel
  139.     Wave w= kernel0
  140.     if( WaveExists(w) )
  141.         rval= CleanupName(S_fileName, 1)
  142.         Duplicate/O w,::$rval
  143.     endif
  144.     KillDataFolder :
  145.     SetDataFolder dfSav
  146.     return rval
  147. end
  148.  
  149. Function WMBPLoadKernel(ctrlName) : ButtonControl
  150.     String ctrlName
  151.     
  152.     String s= WMLoadKernel()
  153. end
  154.  
  155.         
  156.  
  157. Function WMBPConvDoIt(ctrlName) : ButtonControl
  158.     String ctrlName
  159.  
  160.     String pw= WMGetImageWave()
  161.     Wave w= $pw
  162.     if( !WaveExists(w) )
  163.         beep
  164.         return 0
  165.     endif
  166.     ControlInfo popConvSrc
  167.     String kwName= S_value
  168.  
  169.     String dfSav=GetDataFolder(1)
  170.     SetDataFolder WMGetSetKernelDFVariable("")
  171.     Wave kw= $kwName
  172.     SetDataFolder dfSav
  173.     if( !WaveExists(kw) )
  174.         Abort "No kernel wave selected"
  175.         return 0
  176.     endif
  177.     WMSaveWaveBackups(w)
  178.     MatrixConvolve kw, w
  179. End
  180.  
  181.  
  182. Function WMBPUndo(ctrlName) : ButtonControl
  183.     String ctrlName
  184.  
  185.     String pw= WMGetImageWave()
  186.     Wave w= $pw
  187.     if( !WaveExists(w) )
  188.         beep
  189.         return 0
  190.     endif
  191.  
  192.     variable fail= 1
  193.     do
  194.         if( CmpStr(ctrlName,"buttonUndo") == 0 )
  195.             fail= WMRestoreWaveBackups(w,0)
  196.             break
  197.         endif
  198.         if( CmpStr(ctrlName,"buttonRestore") == 0 )
  199.             fail=WMRestoreWaveBackups(w,1)
  200.             break
  201.         endif
  202.         if( CmpStr(ctrlName,"buttonDone") == 0 )
  203.             fail= 0
  204.             DoAlert 2,"Delete backups?"
  205.             if( V_FLag == 3 )                                // cancel button
  206.                 break;
  207.             endif
  208.             if( V_FLag == 1 )
  209.                 WMRestoreWaveBackups(w,-1)
  210.             endif
  211.             DoWindow/K $WinName(0, 64)                // this be us
  212.             KillDataFolder root:Packages:WMImProcess:
  213.             break
  214.         endif
  215.     while(0)
  216.     if( fail )
  217.         Print "no backup waves found"
  218.         beep
  219.     endif
  220. End
  221.  
  222. Function WMWithin(a,b,c)
  223.     variable a,b,c
  224.     
  225.     if( a < b )
  226.         return 0
  227.     endif
  228.     if( a > c )
  229.         return 0
  230.     endif
  231.     return 1
  232. end
  233.  
  234. // WMGetSetKernelDFVariable is a bottleneck proc that
  235. // manages a global string variable in this package that contains the data folder
  236. // in which convolution kernels looked for and loaded. If newDF is not zero length then
  237. // it is taken to be the new path. The value of the variable is returned.
  238. //
  239. Function/S WMGetSetKernelDFVariable(newDF)
  240.     String newDF
  241.     
  242.     String kdfpath= "root:Packages:WMImProcess:kerneldf"    // this should be the only place this literal path is needed
  243.     if( exists(kdfpath) == 0 )
  244.         String/G $kdfpath= GetDataFolder(1)    // first time, set to current DF
  245.     endif
  246.     SVAR kerneldf= $kdfpath
  247.     
  248.     if( strlen(newDF) != 0 )
  249.         kerneldf= newDF
  250.     endif
  251.     
  252.     if( !DataFolderExists(kerneldf) )
  253.         kerneldf= GetDataFolder(1)
  254.         Print "Saved kernel data folder path no longer valid; reset to current data folder"
  255.     endif
  256.  
  257.     return kerneldf
  258. end
  259.  
  260.  
  261.  
  262.  
  263. Function/S WMGetKernelWaveList()
  264.     String dfSav=GetDataFolder(1)
  265.     SetDataFolder WMGetSetKernelDFVariable("")
  266.  
  267.     String s=""
  268.     Variable i=0
  269.     do
  270.         Wave w= WaveRefIndexed("", i, 4)
  271.         if( !WaveExists(w) )
  272.             break
  273.         endif
  274.         if( WaveType(w)!=0 )
  275.             if( WMWithin(DimSize(w,0),3,51) %& WMWithin(DimSize(w,1),3,51) %& (DimSize(w,2) == 0 ) )
  276.                 s += NameOfWave(w)+";"
  277.             endif
  278.         endif
  279.         i+=1
  280.     while(1)
  281.     SetDataFolder dfSav
  282.     return s
  283. end
  284.  
  285.  
  286.  
  287.  
  288. Function/S WMGetKernelDataFolderPopList()
  289.     String dfSav=GetDataFolder(1)
  290.     String kdfpath=  WMGetSetKernelDFVariable("")
  291.     SetDataFolder kdfpath
  292.  
  293.     String s= ""
  294.     if( CmpStr(kdfpath,"root:") == 0 )
  295.         s= "\\M1(No parent;-;"
  296.     else
  297.         SetDataFolder ::
  298.         s= GetDataFolder(0)+";-;"        // looks like we need a GetDataFolderParent function
  299.         SetDataFolder kdfpath
  300.     endif
  301.     s += GetDataFolder(0)+";-;"
  302.     Variable i=0
  303.     do
  304.         String df= GetIndexedObjName(":", 4, i)
  305.         if( strlen(df)==0 )
  306.             break
  307.         endif
  308.         s += df+";"
  309.         i+=1
  310.     while(1)
  311.     SetDataFolder dfSav
  312.     return s+"-;Set to Current Data Folder"
  313. end
  314.  
  315. Function WMPopProcSetDF(ctrlName,popNum,popStr) : PopupMenuControl
  316.     String ctrlName
  317.     Variable popNum
  318.     String popStr
  319.  
  320.     String dfSav=GetDataFolder(1)
  321.     SetDataFolder  WMGetSetKernelDFVariable("")
  322.     
  323.     do
  324.         if( popNum==1 )
  325.             SetDataFolder ::        // set to parent
  326.             WMGetSetKernelDFVariable( GetDataFolder(1) )
  327.             break
  328.         endif
  329.         if( popNum== 3 )
  330.             break // do nothing
  331.         endif
  332.         if( CmpStr(popStr,"Set to Current Data Folder")==0 )
  333.             WMGetSetKernelDFVariable( dfSav )
  334.             break
  335.         endif
  336.         SetDataFolder $popStr
  337.         WMGetSetKernelDFVariable(  GetDataFolder(1) )
  338.     while(0)
  339.     SetDataFolder dfSav
  340.     PopupMenu popKDF,mode=3
  341. End
  342.  
  343.  
  344. // commenting is removed during development
  345. Proc WMImageProcessingPanel()
  346. //Panel0()
  347. //end
  348. //
  349. //Window Panel0() : Panel
  350.     PauseUpdate; Silent 1        | building window...
  351.     NewPanel /W=(347,56,657,298)
  352.     ModifyPanel cbRGB=(65535,54607,32768)
  353.     SetDrawLayer UserBack
  354.     DrawRRect 34,144,284,196
  355.     DrawRRect 34,15,284,83
  356.     SetDrawEnv textxjust= 2
  357.     DrawText 96,34,"NxN Filter:"
  358.     DrawRRect 34,89,284,138
  359.     SetDrawEnv textxjust= 2
  360.     DrawText 95,109,"3x3 Filter:"
  361.     SetDrawEnv textxjust= 2
  362.     DrawText 83,165,"Kernel:"
  363.     SetDrawEnv textxjust= 2
  364.     DrawText 140,188,"DF:"
  365.     PopupMenu popNxN,pos={100,18},size={73,19}
  366.     PopupMenu popNxN,mode=1,value= #"\"median;avg;gauss;min;max;NaNZapMedian;\""
  367.     SetVariable size,pos={74,42},size={70,15},format="%d"
  368.     SetVariable size,limits={3,101,2},value= root:Packages:WMImProcess:size
  369.     SetVariable pasesNxN,pos={58,64},size={115,15},title="passes"
  370.     SetVariable pasesNxN,limits={0,100,1},value= root:Packages:WMImProcess:passesNxN
  371.     Button NxNDoIt,pos={223,40},size={50,20},proc=WMBPNxNDoIt,title="Do It"
  372.     PopupMenu Pop3x3,pos={101,93},size={90,19}
  373.     PopupMenu Pop3x3,mode=1,value= #"\"FindEdges;Point;Sharpen;SharpenMore;gradN;gradNW;gradW;gradSW;gradS;gradSE;gradE;gradNE\""
  374.     SetVariable pases3x3,pos={56,119},size={115,15},title="passes"
  375.     SetVariable pases3x3,limits={0,100,1},value= root:Packages:WMImProcess:passes3x3
  376.     Button DoIt3x3,pos={223,101},size={50,20},proc=WMBPNxNDoIt,title="Do It"
  377.     PopupMenu popConvSrc,pos={85,149},size={113,19}
  378.     PopupMenu popConvSrc,mode=1,value= #"WMGetKernelWaveList()"
  379.     Button DoItConv,pos={223,147},size={50,20},proc=WMBPConvDoIt,title="Do It"
  380.     Button buttonUndo,pos={35,208},size={50,20},proc=WMBPUndo,title="Undo"
  381.     Button buttonRestore,pos={89,208},size={66,20},proc=WMBPUndo,title="Restore"
  382.     Button buttonDone,pos={229,208},size={50,20},proc=WMBPUndo,title="Done"
  383.     Button buttonLoadK,pos={42,172},size={60,20},proc=WMBPLoadKernel,title="Load..."
  384.     PopupMenu popKDF,pos={142,172},size={19,19},proc=WMPopProcSetDF
  385.     PopupMenu popKDF,mode=3,value= #"WMGetKernelDataFolderPopList()"
  386. EndMacro
  387.